﻿package component.formula;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import component.formula.exception.FormulaException;
import component.formula.util.CalculateUtil;
import component.formula.util.StringUtil;

/**
 * 
 * 说明：中文公式解析
 *
 */
public class FormulaParser {
	public final static String IF_KEY = "如果";
	public final static String THEN_KEY = "则";
	public final static String ELSE_KEY = "否则";
	
	public final static String OR_KEY = "或";
	public final static String AND_KEY = "且";
	
	public final static String END_SPLIT = ";";//如果结束的符号
	
	//条件变量包含在[]里面
	public final static String Variable_Left_Key = "[";
	public final static String Variable_Right_Key = "]";
	
	//值变量包含在{}里面
	public final static String Value_Left_Key = "{";
	public final static String Value_Right_Key = "}";
	
	public static String parseFormula(String formula,Map valueMap) throws FormulaException{
		int ifChIndex = formula.indexOf(IF_KEY);
		if(ifChIndex==-1){//没有条件的公式
			String formulaValue = "";
			String name = "";
			for(int i=0;i<formula.length();i++){
				char c = formula.charAt(i);
				if(String.valueOf(c).equals(Variable_Left_Key) || String.valueOf(c).equals(Value_Left_Key)){
					name = "";
					for(int j=i+1;j<formula.length();j++){//寻找对应的变量标志符号
						char c2 = formula.charAt(j);
						if(String.valueOf(c2).equals(Variable_Right_Key) || String.valueOf(c2).equals(Value_Right_Key)){// [ 或 { 为变量的开始
							//System.out.println("name = " + name);
							String value = (String)valueMap.get(name);
							if(value==null){
								value = name;
							}
							formulaValue += value;
							i = j;
							break;
						}else{
							name += c2;
						}
					}
				}
				else{
					formulaValue += c;
				}
			}
			formulaValue = formulaValue.replaceAll("<>", "!=");
			//去掉一些换行符号
			formulaValue = formulaValue.replaceAll("\r", "");
			formulaValue = formulaValue.replaceAll("\n", "");
			FormulaException.debug("formulaValue = " + formulaValue);
			return ExpressionParser.calculate(formulaValue);
		}else{//有条件的中文公式
			String formulaValue = "";
			if(formula.indexOf(END_SPLIT)==-1){
				String[] formulaArr = formula.split(ELSE_KEY);
				String[] ifFormulaArr = formulaArr[0].split(IF_KEY);
				for(int j=0;j<ifFormulaArr.length;j++){
					String ifFormula = ifFormulaArr[j];
					if(!StringUtil.isNull(ifFormula)){
						ifFormula = ifFormula.replaceFirst(THEN_KEY, ",");
						ifFormula = ifFormula.replaceAll(OR_KEY, "||");
						ifFormula = ifFormula.replaceAll(AND_KEY, "&&");
						formulaValue += "if(" + ifFormula + ");";
					}
				}
				if(formulaArr.length>1){
					formulaValue += formulaArr[1];
				}
			}else{
				formula = formula.replaceAll("如果", "if(");
				formula = formula.replaceAll("则", ",");
				formula = formula.replaceAll(END_SPLIT, ");");
				formula = formula.replaceAll("否则", "");
				formula = formula.replaceAll(OR_KEY, "||");
				formula = formula.replaceAll(AND_KEY, "&&");
				formulaValue = formula;
			}
			
			FormulaException.debug("有条件的表达式：" + formulaValue);
			return parseFormula(formulaValue, valueMap);
		}
	}	
	
	public static void main(String[] args) throws FormulaException {
		/**
		 * 条件：
		 * 		如果 ... (... 且,或 ...) ... 则 ... 否则 ...
		 * 		=,<>,>,>=,<,<=
		 */
		String formulaStr = "({基本工资}+[档案工资])+[职级补贴]+([工龄补贴]+[学历补贴]+[职称补贴]+[独生子女补贴])-([养老保险]+[医疗保险]+[失业保险]+[公积金]+[个人所得税]+[工会费])+[补发工资]";
		formulaStr = "({基本工资}+{档案工资})+{职级补贴}";
		formulaStr = "如果 [学历]=大专 且 [学历]=本科  则 {档案工资}+10 ";
		
//		formulaStr = "如果 ({实发金额}-1600)>0 且 ({实发金额}-1600)<=500 则 ({实发金额}-1600)*5/100;";
//		formulaStr += "如果 ({实发金额}-1600)>500 且 ({实发金额}-1600)<=2000 则 ({实发金额}-1600)*10/100-25;";
//		formulaStr += "如果 ({实发金额}-1600)>2000 且 ({实发金额}-1600)<=5000 则 ({实发金额}-1600)*15/100-125;";
//		formulaStr += " 否则 10 ";
		
		formulaStr = "如果 ({实发金额}-1600)>0 且 ({实发金额}-1600)<=500 则 ({实发金额}-1600)*5/100;" +
				"如果 ({实发金额}-1600)>500 且 ({实发金额}-1600)<=2000 则 ({实发金额}-1600)*10/100-25;" +
				"如果 ({实发金额}-1600)>2000 且 ({实发金额}-1600)<=5000 则 ({实发金额}-1600)*15/100-125;";
			
		Map map = new HashMap();
		map.put("基本工资", "1000");map.put("档案工资", "100");
		map.put("职级补贴", "11");
		map.put("工龄补贴", "21");map.put("学历补贴", "22");map.put("职称补贴", "23");map.put("独生子女补贴", "24");
		map.put("养老保险", "31");map.put("医疗保险", "32");map.put("失业保险", "33");map.put("公积金", "34");map.put("工会费", "36");//map.put("个人所得税", "35");
		map.put("补发工资", "-41.242");
		
		map.put("学历", "本科");
		
		map.put("个人所得税", "-41.242");
		map.put("实发金额", "3000");
		
		//parseFormula(formulaStr,map,formulaMap);
		String value = parseFormula(formulaStr,map);
		System.out.println("value = " + value);
		
		//System.out.println((1000+100)+11+(21+22+23+24)-(31+32+33+34+(0-41.242)+36)+(0-41.242));
	}
}